
import java.util.AbstractSet;
import java.util.ArrayList;
import java.util.Iterator;

public class ClosedHashSet extends AbstractSet<Integer> {

    private ArrayList<Integer> arr_first[]; //изначальный массиив
    private int volume = 0;//кол-во элементов заданная при создание экземпляра 
    private int size = 0;//текущее кол во элементов
    
    public ClosedHashSet() throws IllegalArgumentException{
        this.volume=10;
        this.arr_first = new ArrayList[this.volume];
         
         for(int i=0;i<this.volume;i++) {
            arr_first[i]=new ArrayList<Integer>();
         }
     }
    public ClosedHashSet(int _volume) throws IllegalArgumentException{
       this.volume=_volume;
       this.arr_first = new ArrayList[this.volume];
        
        for(int i=0;i<this.volume;i++) {
           arr_first[i]=new ArrayList<Integer>();
        }
    }

    private int hashkey(int value) {
        return ((value >> 11) ^ value) % volume;
    }
    
    public boolean add(int value) throws ArrayIndexOutOfBoundsException,IllegalArgumentException{
      
       if(!contains(value))
       {
	       this.arr_first[hashkey(value)].add(value);
	       this.size++;
	       return true;    
       }
       else
       {
    	   return false;
       }
    }
    
    public boolean remove(int value) {
        int index = hashkey(value);
        for(int elem=0;elem<this.arr_first[index].size();elem++)
        {
           if(this.arr_first[index].get(elem)==value)
           {
              this.arr_first[index].remove(elem) ;
              this.size--;
              return true;
           }
        
        }
        return false;
       
    }
    
    public boolean contains(int value) {
       int index = hashkey(value);
       return this.arr_first[index].contains(value);
   
    }

    
    
    public int size() {
        return this.size;
    }
    
    public void clear() {
       
       for(int elem1=0;elem1<this.arr_first.length;elem1++)
       {
             this.arr_first[elem1].clear();
       }
       
        size = 0;
        
    }
  
    public String toString() {
       String st=new String();
       for(int elem1=0;elem1<this.arr_first.length;elem1++)
       {
             st+=this.arr_first[elem1].toString();
       }
       
        return st;
        
    }
  
   
class MyIterator implements Iterator<Integer> {
     
     int current = 0;
     
     int current_first=0;
     int current_second=0;
     
     int nach_current_first=0;
     int nach_current_second=0;
     
     public MyIterator(int start) {
    	 
             current = start;
            int current_val=0;
            for(int elem1=0;elem1<arr_first.length;elem1++)
             {
               int size_arr=arr_first[elem1].size();
               current_val+=size_arr;
               if(current_val>=start)
               {
                  current_second=current_val-start;  
                  break;
               }
               current_first++;
             }
            nach_current_first=current_first;
            nach_current_second=current_second;      
            
     }
     
    
     public Integer next() {
    	
    	 //System.out.println(arr_first[current_first].size());
	    if(arr_first[current_first].size()>current_second)
	    {
	       //значит в нем 
	    	current_second++;
	    }
	    else//if равен
	    {
	    	if(arr_first.length>current_first)
	        {
	   		 current_first++;
	        }
		   	 else//if нужно сначала массива
		   	 {
		   		 current_first=0;
		   	 }
	    	
	    	current_second=0;
	    }
	    
	    
     
        if(nach_current_first==current_first)
        {
           if(nach_current_second==current_second)
            {
               return null;
            }
        }
        current++;
        /*
	        if(arr_first[current_first].get(current_second)!=null)
	        {
	        	return arr_first[current_first].get(current_second);
	        }
	        else
	        {
	        	return next();
	        }
        */
	        try
	       {
	        	return arr_first[current_first].get(current_second);
	       }
	       catch(Exception e)
	       {
	        	return next();
	       }
	        
     
		       
        }


	@Override
	public boolean hasNext() {
		// TODO Auto-generated method stub
		return true;
	}


	@Override
	public void remove() {
		// TODO Auto-generated method stub
		
	}
        
     }
     
     
     
   

   
  
   

   
   

@Override
public MyIterator iterator() {
	if(this.size()==0)
    {
       return null;
    }
    MyIterator iter = new MyIterator(0);
    return iter;
}
   
	

  
public static void main(String[] args) {
	try
	{
    System.out.println("Size: ");
    ClosedHashSet a;
     a = new ClosedHashSet(10);
     a.add(11);
     a.add(12);
     System.out.println(a.contains(11));
     System.out.println(a.contains(14));
     a.remove(11);
     System.out.println(a.contains(11));
     a.add(13);
     a.add(15);
     a.add(17);
     a.remove(15);
     System.out.println("Empty: " + a.isEmpty());
     System.out.println(a.toString());
    
     Iterator<Integer> iter=a.iterator();
     
        while(iter.hasNext())
        {
        	
        	System.out.println(iter.next());
        }
                // System.out.println(iter.next());
                // System.out.println(iter.next()); 
              
        
         //System.out.println("");
 
	}
	catch(Exception e)
	{
		
	}
     
 }

}